package edu.utwente.sem.hrs;

import java.util.Date;
import java.util.Set;

import ocsf.server.ConnectionToClient;
import edu.utwente.sem.hrs.model.GastRol;
import edu.utwente.sem.hrs.model.Hotel;
import edu.utwente.sem.hrs.model.Kamer;
import edu.utwente.sem.hrs.model.Persoon;
import edu.utwente.sem.hrs.model.Reservering;

public class CommandDispatcher
{
  private Hotel hotel;
  
  public CommandDispatcher(Hotel hotel)
  {
    this.hotel = hotel;
  }

  private String checkIn(Command c)
  {
    String s;
    GastRol g = hotel.getGastByNaam(c.args[0]);
    Kamer k = hotel.getKamerByNummer(Integer.parseInt(c.args[1]));
    Date van = parseDate(c.args[2]);
    Date tot = parseDate(c.args[3]);
    Reservering r = hotel.getReservering(g, k, van, tot);
    if(r != null)
    {
      hotel.checkIn(r);
      s = "Gast is ingecheckd.";
    }
    else
      s = "Reservering bestaat niet. U bent dus niet ingecheckd.";
    return s; 
  }
  
  private String checkUit(Command c)
  {
    String s;
    GastRol g = hotel.getGastByNaam(c.args[0]);
    Kamer k = hotel.getKamerByNummer(Integer.parseInt(c.args[1]));
    Date van = parseDate(c.args[2]);
    Date tot = parseDate(c.args[3]);
    Reservering r = hotel.getReservering(g, k, van, tot);
    if(r != null)
    {
      hotel.checkUit(r);
      s = "Gast is uitgecheckd.";
    }
    else
      s = "Reservering bestaat niet. U bent dus niet uitgecheckd.";
    return s; 
  }
  
  public String execCommand(Command c)
  {
    String l = "Hiervoor moet je ingelogt zijn.";
    String u = "Onvoldoende argumenten";
    boolean x = (boolean) c.client.getInfo("loggedin");
    switch (c.command)
    {
    case "checkIn":
      return x ? (c.args.length >= 4 ? checkIn(c) : u) : l;
    case "checkUit":
      return x ? (c.args.length >= 4 ? checkUit(c) : u) : l;
    case "laadBackup":
      return x ? laadBackup(c) : l;
    case "login":
      return (c.args.length >= 2 ? login(c) : u);
    case "loguit":
      return x ? loguit(c) : l;
    case "maakBackup":
      return x ? maakBackup(c) : l;
    case "maakReservering":
      return x ? (c.args.length >= 3 ? maakReservering(c) : u) : l;
    case "registreerGast":
      return x ? (c.args.length >= 4 ? registreerGast(c) : u) : l;
    case "registreerMedewerker":
      return x ? (c.args.length >= 6 ? registreerMedewerker(c) : u) : l;
    case "toonBeschikbaarheid":
      return x ? (c.args.length >= 2 ? toonBeschikbaarheid(c) : u) : l;
    case "toonKamer":
      return x ? (c.args.length >= 1 ? toonKamer(c) : u) : l;
    case "toonPersoon":
      return x ? (c.args.length >= 1 ? toonPersoon(c) : u) : l;
    case "toonRekeningGast":
      return x ? (c.args.length >= 1 ? toonRekeningGast(c) : u) : l;
    case "toonReservering":
      return x ? (c.args.length >= 4 ? toonReservering(c) : u) : l;
    case "verwijderReservering":
      return x ? (c.args.length >= 4 ? verwijderReservering(c) : u) : l;
    case "help":
    default:
      return help(c);

    }
  }

  private String help(Command c)
  {
    String s = "Dit is de help. Data zijn in d-m-YYYY formaat.\n";
    s += "checkIn\t\t\tnaamGast kamerNr van tot\n";
    s += "checkUit\n";
    s += "laadBackup\t\tbestandsnaam\n";
    s += "login\t\t\tnaam wachtwoord\n";
    s += "loguit\n";
    s += "maakReservering\t\tnaam van tot [kwaliteitKamer]\n";
    s += "maakReservering\t\tnaam kamerNr van tot\n";
    s += "registreerGast\t\tnaam adres telefoonNr creditcardNr\n";
    s += "registreerMedewerker\tnaam adres telefoonNr functie gebruikersnaam wachtwoord\n";
    s += "toonBeschikbaarheid\tvan tot [kwaliteitKamer]\n";
    s += "toonKamer\t\tkamerNr\n";
    s += "toonPersoon\t\tnaam\n";
    s += "toonRekeningGast\tnaam\n";
    s += "toonReservering\t\tnaam kamerNr van tot\n";
    s += "verwijderReservering\tnaam kamerNr van tot\n";
    s += "help\n";
    return s;
  }

  private String laadBackup(Command c)
  {
    String s = "Dit is een dummy.";
    return s;
  }

  private String login(Command c)
  {
    String s;
    if (hotel.verifieerIdentiteit(c.args[0], c.args[1]))
    {
      c.client.setInfo("naam", c.args[0]);
      c.client.setInfo("loggedin", true);
      s = "U bent ingelogd.";
    }
    else
      s = "Uw combinatie van naam en wachtwoord is foutief.";
    return s;
  }

  private String loguit(Command c)
  {
    c.client.setInfo("loggedin", false);
    return "U bent uitgelogd.";
  }

  private String maakBackup(Command c)
  {
    String s = "Dit is een dummy.";
    return s;
  }

  private String maakReservering(Command c)
  {
    Reservering x;
    GastRol g = hotel.getGastByNaam(c.args[0]);
    if (c.args[1].indexOf('-') > 0) // van de vorm naam, van, tot [, kwaliteit]
    {
      Date van = parseDate(c.args[1]);
      Date tot = parseDate(c.args[2]);
      if (c.args.length > 3)
        x = hotel.maakReservering(g, Integer.parseInt(c.args[3]), van, tot);
      else
        x= hotel.maakReservering(g, van, tot);
    }
    else
    // van de vorm naam, kamernummer, van, tot
    {
      Kamer k = hotel.getKamerByNummer(Integer.parseInt(c.args[1]));
      Date van = parseDate(c.args[2]);
      Date tot = parseDate(c.args[3]);
      x= hotel.maakReservering(g, k, van, tot);
    }
    return "Reservering is gemaakt. Uw heeft kamer " + x.getKamer().getKamernummer() + "gereserveerd.";
  }

  public Command parseCommand(String command, ConnectionToClient client)
  {
    int firstSpace = command.indexOf(' ');
    if (firstSpace > 0)
    {
      String com = command.substring(0, firstSpace);
      command = command.substring(firstSpace + 1);
      String[] args = command.split(" ");
      return new Command(com, args, client);
    }
    else
      return new Command(command, new String[0], client);

  }

  @SuppressWarnings("deprecation")
  private Date parseDate(String s)
  {
    String[] x = s.split("-");
    return new Date(Integer.parseInt(x[2]), Integer.parseInt(x[1])-1,
        Integer.parseInt(x[0]));
  }

  private String registreerGast(Command c)
  {
    String naam = c.args[0];
    String adres = c.args[1];
    for (int i = 2; i < c.args.length - 2; i++)
      adres += " " + c.args[i];
    String telefoonnummer = c.args[c.args.length - 2];
    String creditcard = c.args[c.args.length - 1];
    hotel.registreerGast(naam, adres, telefoonnummer, creditcard);
    return naam + " is geregistreerd als gast.";
  }

  private String registreerMedewerker(Command c)
  {
    String naam = c.args[0];
    String adres = c.args[1];
    for (int i = 2; i < c.args.length - 4; i++)
      adres += " " + c.args[i];
    String telefoonnummer = c.args[c.args.length - 4];
    String functie = c.args[c.args.length - 3];
    String username = c.args[c.args.length - 2];
    String password = c.args[c.args.length - 1];
    hotel.registreerMedewerker(naam, adres, telefoonnummer, functie, username,
        password);
    String s = naam + " is geregistreerd als medewerker.";
    return s;
  }

  private String toonBeschikbaarheid(Command c)
  {
    String s;
    Date van = parseDate(c.args[0]);
    Date tot = parseDate(c.args[1]);
    if (c.args.length == 2)
    {
      Set<Kamer> x = hotel.controleerBeschikbaarheid(van, tot);
      if (!x.isEmpty())
      {
        s = "De volgende kamers zijn beschikbaar: ";
        for (Kamer k : x)
          s += k.getKamernummer() + ", ";
        s = s.substring(0, s.length() - 2);
        s += ".";
      }
      else
        s = "Er zijn helaas geen kamers beschikbaar.";
    }
    else
    {
      Set<Kamer> x = hotel.controleerBeschikbaarheid(van, tot,
          Integer.parseInt(c.args[2]));
      if (!x.isEmpty())
      {
        s = "De volgende kamers zijn beschikbaar: ";
        for (Kamer k : x)
          s += k.getKamernummer() + ", ";
        s = s.substring(0, s.length() - 2);
        s += ".";
      }
      else
        s = "Er zijn helaas geen kamers beschikbaar.";
    }
    return s;
  }

  private String toonKamer(Command c)
  {
    String s;
    Kamer k = hotel.getKamerByNummer(Integer.parseInt(c.args[0]));
    if (k != null)
      s = k.toString();
    else
      s = "Deze kamer bestaat niet.";
    return s;
  }
  
  private String toonPersoon(Command c)
  {
    String s;
    Persoon p = hotel.getPersoonByNaam(c.args[0]);
    if (p != null)
      s = p.toString();
    else
      s = "Deze persoon bestaat niet.";
    return s;
  }
  
  private String toonRekeningGast(Command c)
  {
    String s;
    GastRol g = hotel.getGastByNaam(c.args[0]);
    if (g != null)
      s = g.getRekening().prettyPrint();
    else
      s = "Deze persoon bestaat niet.";
    return s;
  }

  private String toonReservering(Command c)
  {
    String s;
    GastRol g = hotel.getGastByNaam(c.args[0]);
    Kamer k = hotel.getKamerByNummer(Integer.parseInt(c.args[1]));
    Date dv = parseDate(c.args[2]);
    Date dt = parseDate(c.args[3]);
    Reservering r = new Reservering(g, k, dv, dt);
    if (k.getReserveringen().contains(r))
      s = k.toString();
    else
      s = "Deze reservering bestaat niet.";
    return s;
  }

  private String verwijderReservering(Command c)
  {
    String s = "";
    GastRol g = hotel.getGastByNaam(c.args[0]);
    Kamer k = hotel.getKamerByNummer(Integer.parseInt(c.args[1]));
    Date van = parseDate(c.args[2]);
    Date tot = parseDate(c.args[3]);
    Reservering r = new Reservering(g, k, van, tot);
    if (k.getReserveringen().contains(r))
    {
      hotel.verwijderReservering(g, k, van, tot);
      s = "Reservering is verwijdert.";
    }
    else
      s = "Reservering bestaat niet en is dus ook niet verwijdert.";
    return s;
  }
}
